use std::{rc::Rc, cell::RefCell};

use crate::{instructions::base::Instruction, rtda::Frame};

// 把null引用推入操作数栈顶
#[derive(Debug, Default)]
pub struct ACONST_NULL { }

impl Instruction for ACONST_NULL {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        frame.borrow().get_operand_stack().borrow_mut().push_ref(None);
    }
}

// 把double型0推入操作数栈顶
#[derive(Debug, Default)]
pub struct DCONST_0 { }

impl Instruction for DCONST_0 {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        frame.borrow().get_operand_stack().borrow_mut().push_double(0.0);
    }
}
#[derive(Debug, Default)]
pub struct DCONST_1 { }

impl Instruction for DCONST_1 {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        frame.borrow().get_operand_stack().borrow_mut().push_double(1.0);
    }
}

/// Push float
#[derive(Debug, Default)]
pub struct FCONST_0 { }

impl Instruction for FCONST_0 {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        frame.borrow().get_operand_stack().borrow_mut().push_float(0.0);
    }
}

#[derive(Debug, Default)]
pub struct FCONST_1 { }

impl Instruction for FCONST_1 {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        frame.borrow().get_operand_stack().borrow_mut().push_float(1.0);
    }
}

#[derive(Debug, Default)]
pub struct FCONST_2 { }

impl Instruction for FCONST_2 {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        frame.borrow().get_operand_stack().borrow_mut().push_float(2.0);
    }
}

// 把int型 -1 推入操作数栈顶
#[derive(Debug, Default)]
pub struct ICONST_M1 { }

impl Instruction for ICONST_M1 {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        frame.borrow().get_operand_stack().borrow_mut().push_int(-1);
    }
}

#[derive(Debug, Default)]
pub struct ICONST_0 { }

impl Instruction for ICONST_0 {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        frame.borrow().get_operand_stack().borrow_mut().push_int(0);
    }
}

#[derive(Debug, Default)]
pub struct ICONST_1 { }

impl Instruction for ICONST_1 {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        frame.borrow().get_operand_stack().borrow_mut().push_int(1);
    }
}

#[derive(Debug, Default)]
pub struct ICONST_2 { }

impl Instruction for ICONST_2 {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        frame.borrow().get_operand_stack().borrow_mut().push_int(2);
    }
}

#[derive(Debug, Default)]
pub struct ICONST_3 { }

impl Instruction for ICONST_3 {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        frame.borrow().get_operand_stack().borrow_mut().push_int(3);
    }
}

#[derive(Debug, Default)]
pub struct ICONST_4 { }

impl Instruction for ICONST_4 {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        frame.borrow().get_operand_stack().borrow_mut().push_int(4);
    }
}

#[derive(Debug, Default)]
pub struct ICONST_5 { }

impl Instruction for ICONST_5 {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        frame.borrow().get_operand_stack().borrow_mut().push_int(5);
    }
}

// Push long constant
#[derive(Debug, Default)]
pub struct LCONST_0 { }

impl Instruction for LCONST_0 {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        frame.borrow().get_operand_stack().borrow_mut().push_long(0);
    }
}

#[derive(Debug, Default)]
pub struct LCONST_1 { }

impl Instruction for LCONST_1 {
    fn execute(&mut self, frame: Rc<RefCell<Frame>>) {
        frame.borrow().get_operand_stack().borrow_mut().push_long(1);
    }
}
